//Abstraktin yliluokan cPot metodit on määritelty tässä tiedostossa.  Käytettävät potentiaalikuopat on perittävä cPot luokasta.
//
//Joonas Koskinen
//Pro Gradu työ
//Jyväskylän Yliopisto

#include "cPot.h"

using namespace std;
//constructor

const double cPot::atomic_length_m = 5.2917720859e-11;
const double cPot::atomic_energy_eV = 27.21138386;
const double cPot::atomic_me = 9.1093826e-31;
const double cPot::atomic_mp = 1.672621637e-27;


cPot::cPot(){
//	filter.push_back(new cFIR);
//	setActiveFilter(0);
    dVecExists=false;
}

//destructor
cPot::~cPot() {
//	for(unsigned int i=0; i<filter.size();i++) {
//		delete filter[i];
//	}
}

void cPot::setDepth(double value) {
	depth=value;
}

void cPot::setWidth(double value) {
	//TODO:Tähän fiksu virhekäsittely jos value<0
	if(value <0) {value=1;}
	width = value;
	//pot_left = -1*value/2;
	//	pot_right = value/2;	
}

string cPot::getName() const{
	return name;
}

void cPot::setName(string value) {
	name=value;
}

double cPot::getMinEnergy() const{
    std::cout << "Returning minimum energy " << minEnergy << endl;
	return minEnergy;
}

void cPot::setMinEnergy(double value) {
	this->minEnergy=value;
}

double cPot::getDepth() const{
	return depth;
}

double cPot::getWidth() const{
	return width;
}

double cPot::getUniverse() const{
	return universe;
}

void cPot::setUniverse(double value) {
	universe = value;
}

void cPot::setPotLeft(double value) {
	potLeft=value;
	//set_width( fabs(value) + fabs(pot_right) );
}

void cPot::setPotRight(double value) {
	potRight=value;
	//set_width( fabs(value) + fabs(pot_left)  );
}

void cPot::setFx(double value) {
	fx = value;
//	filter[activefilter]->setf_fx(value);
}

void cPot::setTx(double value) {
	tx = value;
//	filter[activefilter]->setf_tx(value);
}

double cPot::getTx() const{
	return tx;
}

double cPot::getFx() const{
	return fx;
}

double cPot::getPotLeft() const{
	return potLeft;
}

double cPot::getPotRight() const{
	return potRight;
}

void cPot::set_k(double value) {
	k=value;
}

void cPot::setUniLeft(double value){
	universeLeft = value;
}

void cPot::setUniRight(double value){
	universeRight = value;
}

double cPot::get_k() const {
	return k;
}

void cPot::setPotMin() {
	double min, minx = 0.0;
	double s=0.1;
	min=getPotentialValueAt(tx);
	for(double i=tx;i<fx;i=i+s) {
		if(getPotentialValueAt(i) < min){min=getPotentialValueAt(i); minx=i;}
	}
	potMin = minx;
}

double cPot::getPotMin() const{
	return potMin;
}

void cPot::set_l(unsigned int value) {
	l=value;
}

unsigned int cPot::get_l() const{
	return l;
}

void cPot::setGlue(double value) {
	glue = value;
}

double cPot::getGlue() const{
	return glue;
}

vector<double> cPot::getDiscontVector() const {
    return discont;
}

void cPot::setDiscontVector(vector<double> value) {
    discont = value;
    setDiscontVectorExists(true);
}

void cPot::setDiscontVectorExists(bool value) {
    dVecExists = value;
}

bool cPot::discontVectorExists() const {
    return dVecExists;
}

//bool cPot::isUsingFilter() const
//{
//    return usingFilter;
//}
//
//void cPot::setUsingFilter(bool value)
//{
//    usingFilter=value;
//    if(value == true) {
//    	filter[activefilter]->calculate(this);
//    }
//    if(value == false) {
//    	filter[activefilter]->clear_input();
//    	filter[activefilter]->clear_output();
//    }
//}
//
//vector<double> cPot::getFilterOutput() const
//{
//    return filter[activefilter]->getOutput();
//}
//
//vector<double> cPot::getFilterInput() const
//{
//	return filter[activefilter]->getInput();
//}
//
//void cPot::setFilterStep(double value){
//	filter[activefilter]->setStep(value);
//}
//
//double cPot::getFilterStep() const {
//	return filter[activefilter]->getStep();
//}
double cPot::calculateGluepoint(double energy) {
	double glue = 0.0;
	bool first = false;
	bool second = false;
//x-coordinate where value of given energy is higher than the
//value of potential at x for the first time.
	double energy_over=getPotLeft();
//x-coordinate where value fo given energy is lower than the
//value of potential at x for the first time after previous coordinate.
	double energy_under = getPotRight();
	double step = (getPotRight() - getPotLeft()) / 100.0;

	for(int i=1; i<100; i++) {

		if(energy > potential(step*i + getPotLeft()) && first == false) {
			energy_over = step*i + getPotLeft();
			first = true;
		}

		if(energy < potential(step*i + getPotLeft()) && first == true && second == false) {
			energy_under = step*i + getPotLeft();
			second = true;
		}
	}

	if(first == true && second == true) {
		glue = (energy_over + energy_under + 0.2) / 2.0;
	}
	else {
                //Making sure that the gluepoint is not exactly in the middle.
		glue = (getPotLeft() + getPotRight() + 3.0)/2.0;
	}

	return glue;
}

double cPot::getUniverseRight() const {
    return universeRight;
}

double cPot::getUniverseLeft() const {
    return universeLeft;
}

//double cPot::getFilteredPot(double x) {
//	return filter[activefilter]->getFilteredPot(x);
//}
//
//unsigned int cPot::getActiveFilter() const {
//	return activefilter;
//}
//
//void cPot::setActiveFilter(unsigned int value) {
//
//	this->activefilter = value;
//}
//
//unsigned int cPot::getFilterOutputSize() const {
//	return filter[activefilter]->getOutputSize();
//}
//
double cPot::potential(double x) {
        return getPotentialValueAt(x);
}
